package handler

import (
	"code.byted.org/mobaijie/access/mail"
	"code.byted.org/mobaijie/sender/define"
	"context"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"strings"
)

// 解析eml格式数据
func ParseEmail(ctx context.Context, path string) (error, *define.EmlParseData) {
	// 先读eml文件
	err, eml := ReadEmlContentFromFile(path)
	parseResult, err := mail.Parse(ctx, eml)
	//imageList := make([]string, 0)
	imageAttachmentList := make([]string, 0)
	otherAttachmentList := make([]string, 0)
	for _, attachment := range parseResult.Attachments {
		// 处理图片附件
		if strings.Contains(attachment.Filename, ".png") || strings.Contains(attachment.Filename, ".jpg") || strings.Contains(attachment.Filename, ".gif") || strings.Contains(attachment.Filename, "jpeg") {
			contentType := attachment.Header.Get(define.ContentType)
			contentId := attachment.Header.Get(define.ContentID)
			imageAttachment := fmt.Sprintf(define.PicAttachmentHead, contentType, contentId, base64.StdEncoding.EncodeToString(attachment.Content))
			imageAttachmentList = append(imageAttachmentList, imageAttachment)
			// log.Infof("imageAttachment: %s", imageAttachment)
		} else {
			contentType := attachment.Header.Get(define.ContentType)
			otherAttachment := fmt.Sprintf(define.StreamAttachmentHead, contentType, attachment.Filename, base64.StdEncoding.EncodeToString(attachment.Content))
			otherAttachmentList = append(otherAttachmentList, otherAttachment)
			// log.Infof("streamAttachment: %s", otherAttachment)
		}
	}
	// log.Infof("imageAttachmentList: %+v", imageAttachmentList)
	// log.Infof("otherAttachmentList: %+v", otherAttachmentList)
	if err != nil {
		log.Errorf("parse eml fail, err: %s", err.Error())
		return err, nil
	}

	bodyHtml := *parseResult.Message.Content.BodyHtml
	// 在这里先处理了一下plain text
	res := &define.EmlParseData{
		AllContent:        bodyHtml,
		StreamAttachments: otherAttachmentList,
		PlainText:         getPlainText(bodyHtml),
		ImageAttachments:  imageAttachmentList,
	}
	// log.Infof("bodyHtml: %s", bodyHtml)
	return nil, res
}

// 从eml文件中获取原生内容
func ReadEmlContentFromFile(path string) (error, []byte) {
	emlRaw, err := ioutil.ReadFile(path)
	if err != nil {
		log.Errorf("read eml fail, err: %s", err.Error())
	}
	log.Infof("read email file success")
	return nil, emlRaw
}

// 获取正文纯文字内容
func getPlainText(htmlBody string) string {
	res := htmlBody
	index := 0
	for {
		b1, newIndex := deleteLink(&res, index)
		index = newIndex
		if !b1 {
			break
		}
	}
	for {
		b2 := deleteImg(&res)
		if !b2 {
			break
		}
	}
	return "<h1>plain text with mail address</h1>" + res
}

// 删除href为非邮件地址a标签链接
func deleteLink(body *string, from int) (bool, int) {
	if body == nil || strings.TrimSpace(*body) == "" || from >= len(*body) {
		return false, -1
	}
	preBody := *body
	bodyString := preBody[from:]
	startIndex := strings.Index(bodyString, "<a")
	if startIndex == -1 {
		return false, -1
	}
	endIndex := strings.Index(bodyString[startIndex+2:], "</a>") + startIndex + 2
	res := bodyString[startIndex : endIndex+4]
	hrefStartIndex := strings.Index(res, "href=\"")
	hrefEndIndex := strings.Index(res[hrefStartIndex+6:], "\"") + hrefStartIndex + 6
	href := res[hrefStartIndex+6 : hrefEndIndex]
	if define.MailRegexp.MatchString(href) || define.MailToRegexp.MatchString(href) {
		return true, endIndex + 1 + from
	}
	*body = strings.Replace(preBody, res, "", 1)
	return true, endIndex + 1 + from - len(res)
}

// 删除html中的图片标签
func deleteImg(body *string) bool {
	if body == nil || strings.TrimSpace(*body) == "" {
		return false
	}
	bodyString := *body
	startIndex := strings.Index(bodyString, "<img ")
	if startIndex == -1 {
		return false
	}
	endIndex := strings.Index(bodyString[startIndex+5:], ">") + startIndex + 5
	res := bodyString[startIndex : endIndex+1]
	*body = strings.Replace(bodyString, res, "", 1)
	return true
}
